import { Workbook } from 'exceljs';
import { ICommonParams } from '@feidao/service/interfaces';
import zip from '@feidao/web/atom/nodejs/zip/zip';

// todo msg的参数定义修改
export default async function atom(msg: ICommonParams, action_id: string, session_id: string, spaceid: string) {

	/**
	 * 参数
	 * 访问下载地址:http://127.0.0.1:8889/export-excel?id=ceshi&spaceid=webtest
	 * 传入了两个参数
	 */

	// 接收参数
	const query = msg.query;
	const _id = query.id;
	const _spaceid = query.spaceid;


	// 文档地址 https://github.com/guyonroche/exceljs#readme
	// 使用示例 https://feidao-edu.gitee.io/taoqf/201805020916.html

	// 创建一个实例
	const wb = new Workbook();

	// 可以添加文件描述
	wb.creator = 'feidao';
	// creator: string;
	// lastModifiedBy: string;
	// created: Date;
	// modified: Date;
	// lastPrinted: Date;
	// Set workbook dates to 1904 date system
	// wb.properties.date1904 = true;
	// 	wb.views = [
	//   {
	//     x: 0, y: 0, width: 10000, height: 20000,
	//     firstSheet: 0, activeTab: 1, visibility: 'visible'
	//   }
	// ]

	// 添加一个页签，可以添加多个页签
	// 不输入名称则使用默认名称，可以针对该页签添加属性
	// options = {properties:{}, pageSetup:{}, views:[{}]}
	const dict1 = wb.addWorksheet();// 该页签的默认名称为`sheet1`

	// 在页签dict1中添加表头，表头一定在第一行（如果其他内容在第一行，添加的表头也在第一行）
	// { header: '教学班编号', key: 'teaching_class_id', width: 20, outlineLevel: 2, hidden: false, style: { numFmt: '', font: {}, alignment: {}, border: {}, fill: {} } },
	// outlineLevel 设置折叠层级
	// numFmt 数据格式 numFmt = '0.00%'; numFmt: 'dd/mm/yyyy' numFmt = '"£"#,##0.00;[Red]\-"£"#,##0.00'; numFmt = '# ?/?';
	dict1.columns = [
		{ header: '教学班编号' },
		{ header: '教学班名称', key: 'teaching_class', width: 20, outlineLevel: 1 },// B
		{ header: '学号', key: 'student_id', width: 20, outlineLevel: 2, hidden: true },// C
		{ header: '姓名', key: 'student_name', width: 20, outlineLevel: 1 },// D
		{ header: '平时成绩1', key: 'ordinary_performance1', width: 20, style: { numFmt: '0.00%' } },// E
		{
			header: '省', key: 'ordinary_performance2', width: 20, style: {
				font: {
					// name: '宋体', // 字体名称
					// size: 15, // 字体大小
					// family: 1, // 1 - Serif, 2 - Sans Serif, 3 - Mono, Others - unknown
					// scheme: 'minor',
					charset: 1, // 字符集 1, 2, etc.
					// color: { argb: 'FFFF00', theme: 0 }, // 字体颜色
					// bold: true, // 加粗
					// italic: true, // 斜体
					// underline: 'doubleAccounting', // 下划线
					// strike: true // 删除线
					outline: true
				}
			}
		},// F
		{
			header: '市', key: 'ordinary_performance3', width: 20, style: {
				alignment: {
					// horizontal: 'left', // 水平距左
					// vertical: 'justify', // 垂直 justify：两端对齐
					// wrapText: true, // 自动换行
					// indent: 20, // 缩进
					// readingOrder: 'ltr'
					// textRotation: 'vertical' // 文本回转
				}
			}
		},
		{
			header: '区', key: 'ordinary_performance4', width: 20, style: {
				border: {
					// top: {
					// 	style: 'mediumDashDot',
					// 	color: {
					// 		argb: '#fff'
					// 	}
					// },
					// left: {
					// 	style: 'thin',
					// 	color: {
					// 		argb: '#fff'
					// 	}
					// },
					// bottom: {
					// 	style: 'dotted',
					// 	color: {
					// 		argb: '#fff'
					// 	}
					// },
					// right: {
					// 	style: 'medium',
					// 	color: {
					// 		argb: '#fff'
					// 	}
					// },
					diagonal: {
						up: true,
						down: true
					}
				}
			}
		},
		{
			header: '平时成绩5', key: 'ordinary_performance5', width: 20, style: {
				fill: {
					// type: 'pattern', // 填充内容，pattern 图案
					// pattern: 'darkDown', // 图案形状
					// bgColor: {
					// 	argb: '008844'
					// },
					// fgColor: {
					// 	argb: 'FFB7DD' // 图案颜色
					// }
					type: 'gradient', // 渐变
					// gradient: 'angle', //
					// degree: 90, // 90：垂直，0：水平，45：斜上，135：斜下，
					gradient: 'path', // 辐射
					center: { left: 0.5, top: 0.5 }, // left=top=0.5 中心辐射，其他值为角度辐射
					stops: [{ position: 0, color: { argb: 'BB5500' } }, { position: 1, color: { argb: '003377' } }] // position：0和1,
				}
			}
		}
	];

	/**
	 * 添加行数据
	 */

	dict1.addRows([{ teaching_class_no: '测试001', teaching_class: '测试001', student_id: '测试001', student_name: '测试001', ordinary_performance1: '测试001', ordinary_performance2: '测试001', ordinary_performance3: '测试001', ordinary_performance4: '测试001', ordinary_performance5: '测试001' }]);

	dict1.addRow({ teaching_class_no: '测试002', teaching_class: '测试002', student_id: '测试002', student_name: '测试002', ordinary_performance1: '测试002', ordinary_performance2: '测试002', ordinary_performance3: '测试002', ordinary_performance4: '测试002', ordinary_performance5: '测试002' });

	// 设置固定下拉数据

	/**
	 * 设置第四列，每一行单元格可以下拉选择，选项为`学生名称1、学生名称2`
	 * 设置第五列，每一行单元格可以下拉选择，选项为`男，女`
	 */

	// const columns = dict1.getColumn(4);
	// // 循环每一个单元格
	// columns.eachCell((cell, rowNumber) => {
	// 	// 回调函数中参数说明，cell为单元格对象，rowNumber即当前单元格所在的行从1开始
	// 	cell.dataValidation = {
	// 		type: 'list',
	// 		formulae: [`"学生名称1,学生名称2"`]
	// 	};
	// });
	// 多个下拉选项使用英文','分隔
	for (let idx = 1; idx < 5000; idx++) {
		const element = dict1.getCell(`E${idx}`);
		element.dataValidation = {
			type: 'list',
			formulae: [`"男,女"`]
		};
	}

	// 这两个选择列单元格的区别为：getColumn只能获取到已有数据的行单元格
	// getCell是根据单元格编号获取


	/**
	 * 下拉数据来源于数据库，并将选择对应的编号带过来
	 */

	// 1、将数据渲染到页签中
	// 创建的页签传入页签名称，符合变量规范，不能是excel中的关键字
	const dict2 = wb.addWorksheet('学生信息');
	// dict2.state = 'hidden'; // 将页签隐藏

	// 设置页签属性，默认行高
	// dict2.properties.defaultRowHeight = 15;
	// dict2.properties.dyDescent = 66;
	// dict2.properties.outlineLevelCol = 2;
	// dict2.properties.outlineLevelRow = 4;
	// dict2.properties.showGridLines = true;
	dict2.properties.tabColor = { argb: 'A42D00' }; // 设置页签的背景颜色

	// dict2.pageSetup.firstPageNumber = 10; // 起始页码
	// dict2.pageSetup.fitToPage = true; // 设置缩放
	// dict2.pageSetup.fitToHeight = 20; // 页高
	// dict2.pageSetup.fitToWidth = 20; // 页宽

	dict2.pageSetup.margins = {
		top: 1,
		left: 1,
		bottom: 1,
		right: 1,
		header: 1,
		footer: 1
	};

	dict2.pageSetup.orientation = 'landscape'; // 版式，横版
	dict2.pageSetup.paperSize = 9; // 纸张 A4
	dict2.pageSetup.printArea = 'A1:G20'; // 打印区域
	dict2.pageSetup.printTitlesRow = '1:2'; // 打印头部信息，每页显示的头部信息


	// 设置页面属性
	// 添加第一行数据，`学生信息`合并横向两个单元格
	dict2.addRow(['学生信息', '']);
	dict2.mergeCells('A1:B1');
	// 将学生数据添加
	// 表头
	dict2.addRow(['学生姓名', '学生编号']);
	dict2.addRows([['张三', '001'], ['李四', '002'], ['王五', '003']]);

	// 设置第四列，每一行单元格可以下拉选择，选项为`学生名称1、学生名称2`

	// 公式说明 学生信息!$A$3:$A$4 `学生信息!`页签名称，`$A$3:$A$4`选择的区域

	const columns = dict1.getColumn(4);
	// 循环每一个单元格
	columns.eachCell((cell, rowNumber) => {
		if (rowNumber > 1) {
			// 回调函数中参数说明，cell为单元格对象，rowNumber即当前单元格所在的行从1开始，不包含第一行
			cell.dataValidation = {
				type: 'list',
				formulae: [`=学生信息!$A$3:$A$5`]
			};
		}
	});

	// VLOOKUP公式说明，`$D${rowNumber}`依据的单元格，`学生信息!$A$3:学生信息!$B$5`筛选的范围，即某一个页签中的数据范围，依据单元格的内容须在筛选范围最左侧，`2`依据筛选内容返回的数据所在筛选范围内的列数（从1开始），`0`精确匹配

	const column3 = dict1.getColumn(3);
	column3.eachCell((cell, rowNumber) => {
		if (rowNumber > 1) {
			// 回调函数中参数说明，cell为单元格对象，rowNumber即当前单元格所在的行从1开始，不包含第一行
			cell.value = {
				formula: `=VLOOKUP($D${rowNumber},学生信息!$A$3:学生信息!$B$5,2, 0)`,
				result: ''
			};
		}
	});

	/**
	 * 对单元格数据进行数据验证
	 */


	for (let idx = 1; idx < 5000; idx++) {
		const element = dict1.getCell(`A${idx}`);

		// 第一列输入的内容唯一性验证
		element.dataValidation = {
			type: 'custom',
			formulae: [`=countif(A1:A5000,A${idx})=1`],
			showErrorMessage: true
		};

		// 第一列输入的数据内容不等于某些值
		// element.dataValidation = {
		// 	type: 'whole', // 整数
		// 	formulae: [2, 10], // 区间
		// 	operator: 'between',
		// 	showErrorMessage: true
		// };


		// 第一列输入的数据长度不能超过20
		// element.dataValidation = {
		// 	type: 'textLength', // 数据验证类型
		// 	formulae: [20], // 值
		// 	allowBlank: false, // 忽略空值
		// 	operator: 'lessThan', // 比较类型，小于
		// 	prompt: '提示内容', // 提示信息内容
		// 	promptTitle: '提示标题', // 提示信息标题
		// 	showInputMessage: true, // 显示提示信息
		// 	error: '错误信息', // 错误信息内容
		// 	errorTitle: '错误标题', // 错误信息标题
		// 	showErrorMessage: true, // 显示错误提示信息
		// 	errorStyle: 'information' // 错误信息图标样式，error 错误，warning 警告，information 信息
		// };
	}


	// 级联数据，省市区

	// 例如数据库存储的数据格式为[{id:'',name:'', pid:''}]
	const cascade_data = [{ id: '001', name: '河南省', pid: '' }, { id: '002', name: '河北省', pid: '' }, { id: '003', name: '山东省', pid: '' }, { id: '0011', name: '郑州市', pid: '001' }, { id: '0012', name: '濮阳市', pid: '001' }, { id: '00111', name: '金水区', pid: '0011' }, { id: '00112', name: '中原区', pid: '0011' }, { id: '00121', name: '南乐县', pid: '0012' }, { id: '00122', name: '清丰县', pid: '0012' }, { id: '0031', name: '聊城市', pid: '003' }, { id: '0032', name: '济南市', pid: '003' }, { id: '00311', name: '高唐县', pid: '0031' }, { id: '00312', name: '阳谷县', pid: '0031' }, { id: '00321', name: '天桥区', pid: '0032' }, { id: '0021', name: '石家庄市', pid: '002' }, { id: '0022', name: '唐山市', pid: '002' }, { id: '00211', name: '长安区', pid: '0021' }, { id: '00212', name: '新华区', pid: '0021' }, { id: '00221', name: '路北区', pid: '0022' }, { id: '00222', name: '路南区', pid: '0022' }];

	// 对数据做处理，将省、市、区数据进行分别渲染到不同的页签上

	// 省数据，数据处理后的结构符合单元格渲染数据结构，此数据结构为[['河南省'],['河北省'],['山东省']]
	const pro_data = cascade_data.filter((item) => {
		return item.pid === '';
	}).reduce((pre, cur, idx, array) => {
		const name = cur.name;
		pre.push([name]);
		return pre;
	}, []);

	const dict3 = wb.addWorksheet('省');
	dict3.addRows(pro_data);

	// 市数据，数据处理后的结构符合单元格渲染数据结构，并且在渲染的市数据单元格上添加名称管理器，名称管理器的值则为市的名称，此数据结构为[['河南省',['郑州市','濮阳市']],['河北省',['石家庄市','唐山市']],['山东省',['济南市','聊城市']]
	const city_data = cascade_data.filter((item) => {
		return item.pid === '';
	}).reduce((pre, cur, idx, array) => {
		const id = cur.id;
		const name = cur.name;
		// 获取市数据
		const c_data = cascade_data.filter((info) => {
			return info.pid === id;
		}).reduce((pre1, cur1, idx1, array1) => {
			pre1.push(cur1.name);
			return pre1;
		}, []);
		const arr = [name, c_data];
		pre.push(arr);
		return pre;
	}, []);

	const dict4 = wb.addWorksheet('市');
	city_data.forEach((item, idx) => {
		const name = item[0];
		const data = item[1];
		dict4.addRow(data);
		// 获取刚渲染的行
		const r = dict4.getRow(idx + 1);
		// 获取每一个单元格，在单元格上添加名称管理器
		r.eachCell((cell, colNumber) => {
			// 设置单元格名称管理器
			cell.addName(name);
		});
	});

	// 区数据，数据机构和市数据结构一致并添加名称管理器
	const area_data: any[] = [];
	cascade_data.filter((item) => {
		return item.pid === '';
	}).map((pro_item) => {
		const id = pro_item.id;
		const c_data = cascade_data.filter((item) => {
			return item.pid === id;
		}).map((c_item) => {
			const cid = c_item.id;
			const name = c_item.name;
			const a_data = cascade_data.filter((item) => {
				return item.pid === cid;
			}).reduce((pre, cur, idx, array) => {
				pre.push(cur.name);
				return pre;
			}, []);
			area_data.push([name, a_data]);
		});
	});

	const dict5 = wb.addWorksheet('区');
	area_data.forEach((item, idx) => {
		const name = item[0];
		const data = item[1];
		dict5.addRow(data);
		const r = dict5.getRow(idx + 1);
		r.eachCell((cell, colNumber) => {
			// 添加名称管理器，name要以字母或下划线开头，不能包含空格，不能与excel内部或者工作薄中其他对象名称冲突
			cell.addName(name);
		});
	});

	/**
	 * 开始在第一个页签中设置省，市，区数据来源
	 */

	/**
	 * 省
	 */
	for (let idx = 1; idx < 5000; idx++) {
		const element = dict1.getCell(`F${idx}`);
		element.dataValidation = {
			type: 'list',
			formulae: [`=省!$A$1:$A$${pro_data.length + 1}`]
		};
	}

	/**
	 * 市
	 */
	for (let idx = 1; idx < 5000; idx++) {
		const element = dict1.getCell(`G${idx}`);
		element.dataValidation = {
			type: 'list',
			formulae: [`=INDIRECT(F${idx})`]
		};
	}

	/**
	 * 区
	 */
	for (let idx = 1; idx < 5000; idx++) {
		const element = dict1.getCell(`H${idx}`);
		element.dataValidation = {
			type: 'list',
			formulae: [`=INDIRECT(G${idx})`]
		};
	}

	/**
	 *  导出单个文件
	 */

	// 获取内容buff
	const buff = await wb.xlsx.writeBuffer() as Buffer;
	// 返回数据,键为固定内容,attachment为文件名称
	// return {
	// 	buff,
	// 	content_type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
	// 	attachment: '表格下载.xlsx'
	// };

	/**
	 * 导出压缩包
	 */

	const res = await zip({ file: buff, path: 'zip/测试.xlsx' });
	// const res = await zip({ file: buff, path: '测试.xlsx' });
	return {
		attachment: '压缩包名称.zip',
		buff: res,
		content_type: 'application/octet-stream'
	};

}
